﻿using EasyI18n.Api.Infrastructure.DataPersistence.MongoDb;
using EasyI18n.Api.Infrastructure.DataPersistence.MongoDb.Entities;
using EasyI18n.Api.Infrastructure.JwtFunction;
using EasyI18n.Api.Primary.Contracts.Bases;
using EasyI18n.Api.Primary.Contracts.Users;
using EasyI18n.Api.Realization.Bases;
using FluentValidation;
using Mediator.Net.Context;
using MongoDB.Driver;
using Shouldly;

namespace EasyI18n.Api.Realization.Handlers.Users;

public class RegisterUserHandler(
    IDocumentAccessor<SystemUser> systemUsersDocs,
    IPasswordHasher passwordHasher
    ) : IRegisterUserContract
{
    public void Validate(ContractValidator<RegisterUserCommand> validator)
    {
        validator.RuleFor(x => x.UserName).NotEmpty();
        validator.RuleFor(x => x.Password).NotEmpty();
    }

    public void Test(TestContext<RegisterUserCommand> context)
    {
        var newUserCase = context.CreateTestCase();
        newUserCase.Message = new RegisterUserCommand()
        {
            UserName = "BILLIE.L",
            Password = "123456"
        };

        newUserCase.Assert = async  _ =>
        {
            var userCursor = await systemUsersDocs.Collection.FindAsync(x => x.UserName == newUserCase.Message.UserName);
            var userList = await userCursor.ToListAsync(); // 

            userList.ShouldNotBeNull();
            userList.First().UserName.ShouldBe("BILLIE.L");
            passwordHasher.VerifyHashedPasswordV3(userList.First().PasswordHash,newUserCase.Message.Password).ShouldBeTrue();
        };
    }

    public async Task Handle(IReceiveContext<RegisterUserCommand> context, CancellationToken cancellationToken)
    {
         
        var userFilter = await systemUsersDocs.Collection
            .FindAsync(x=>x.UserName == context.Message.UserName, cancellationToken: cancellationToken);
    
        if (await userFilter.AnyAsync(cancellationToken))
        {
            throw new BusinessException("当前用户名已存在", BusinessExceptionTypeEnum.DataDuplication);
        }
        var newUser = new SystemUser();
        newUser.UserName = context.Message.UserName;
        newUser.PasswordHash = passwordHasher.HashPasswordV3(context.Message.Password);

        await systemUsersDocs.Collection.InsertOneAsync(newUser, new InsertOneOptions(), cancellationToken);
    }
}